package be.djdb.game.essetials;


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;

import be.djdb.Statics;
import be.djdb.game.players.Opponent;
/**
 * @author user
 *
 */
public class MyLevel extends JPanel{
	public final static int blocksize = 35;
    protected final int NrOfBlocks = 24;//pieces of blocks one line
    public int Xsize ;//horizontal
    public int Ysize;//vertical
	protected short[] screendata =new short[NrOfBlocks * NrOfBlocks];
	public MyPlayer player;
	Font smallfont = new Font("Helvetica", Font.BOLD, 14);
    public Color mazecolor =new Color(5, 100, 5);
    public Color dotcolor = new Color(192, 192, 0);
	private Dimension d;
	public Opponent[] opponents;
	private short[] leveldata =new short[NrOfBlocks * NrOfBlocks];
	public MyLevel(MyPlayer player,short[] leveldata) {
		System.arraycopy(leveldata, 0, this.screendata,0,leveldata.length);
		System.arraycopy(leveldata, 0, this.leveldata,0,leveldata.length);
		this.player = player;
        Xsize=NrOfBlocks*blocksize;
        Ysize=NrOfBlocks*blocksize;
        d = new Dimension(Xsize, Ysize);
   	 	setBackground(Color.black);
   	 	setFocusable(true);
   	 	setDoubleBuffered(true);
   	 	setSize(d);
	}
	public int getBlocksize() {
		return blocksize;
	}
    public void paint(Graphics2D g){
    	System.out.print("paint=>"+toString());
        g.setColor(Color.black);
        g.fillRect(0, 0, d.width, d.height);
        DrawMaze(g);
    }
    public void DrawMaze(Graphics2D g) {
        short i = 0;
        int x, y;
        for (y = 0; y < Ysize; y += blocksize) {
            for (x = 0; x < Xsize; x += blocksize) {
                g.setColor(mazecolor);
                g.setStroke(new BasicStroke(2));
                if(Statics.FOLLOW){	log(Level.FINE,"left ?"+(screendata[i] & Direction.LEFT.getvalue()));}
                if (screendata[i] != 0){
	                if (!canMoveLeft(screendata[i],x)){
	                	if(Statics.FOLLOW){	log(Level.FINE,"LEFT");}
	                    g.drawLine(x, y, x, y + blocksize - 1);
	                }
	                if (!canMoveUp(screendata[i],y)){
	                    g.drawLine(x, y, x + blocksize - 1, y);
	                }
	                if (!canMoveRight(screendata[i],x)){
	                    g.drawLine(x + blocksize - 1, y, x + blocksize - 1,y + blocksize - 1);
	                }
	                if (!canMoveDown(screendata[i],y)){
	                    g.drawLine(x, y + blocksize - 1, x + blocksize - 1,y + blocksize - 1);
	                }
	                if (screendata[i]%5 == 0){ // draws point
	                    g.setColor(dotcolor);
	                    g.fillRect(x + 11, y + 11, 4, 4);
	                }
                }
                i++;
            }
        }
    }
	private static  void log(Level level, String msg ){
	    String tag ="<>>>>*"+Statics.LIBNAME+"-"+Statics.COPYRIGHTBY+"*<<<<>";
	    Logger.getLogger(Level0.class.getName()).log(level, tag + msg);
	}
    /**
     * @param lenght
     * @return
     */
    protected boolean isblockend(int lenght){
    	return (lenght%blocksize==0);
    }
    /**
     * @param lenght
     * @return
     */
    protected boolean isblockstart(int lenght){
    	return ((lenght+blocksize)%blocksize==0);
    }
    /**
     * @param pos actualposition
     * @param dir actualdirection
     * @return
     */
    public boolean CanChangeDirection(MyPos pos,Direction dir) { //direction
    	int x =pos.x;
    	int y =pos.y;
    	short block = screendata[getblockposition(x,y)];
    	if(Direction.UP== dir){
    		if(!isblockend(pos.y))return false;
    		return isblockend(pos.y);
		}
	    if(dir == Direction.DOWN){
	    	if(!isblockstart(pos.y))return false;
	    	return isblockstart(pos.y);
	    }
	    if(dir == Direction.LEFT){
	    	if(!isblockend(pos.x))return false;
	    	return isblockend(pos.x);
		}
	    if(dir == Direction.RIGHT){if(Statics.FOLLOW){System.out.print("RIGHT");}
	       if(!isblockend(pos.x))return false;
	       return isblockend(pos.x);
	    }
    	return true;
    }
    /**
     * @param block
     * @return
     */
    protected boolean canMoveUp(short block,int y){
		if (y<0)return false;//out of level
    	//if (y%blocksize==0)return true;
    	return block%Direction.UP.getvalue() != 0;
    }
    /**
     * @param block
     * @return
     */
    protected boolean canMoveDown(short block, int y){
		if (y>Ysize)return false;//out of level
		//down of block see position is lefttop[pos+blocksizen]
    	if (((y+blocksize-1)%blocksize==0))return true;
    	return block%Direction.DOWN.getvalue()!= 0;
    }
    /**
     * @param block
     * @return
     */
    protected boolean canMoveLeft(short block,int x){
		if (x<0)return false;//out of level
		if (!isblockend(x))return true;
    	return block%Direction.LEFT.getvalue() != 0;
    }
    /**
     * @param block
     * @return
     */
    protected boolean canMoveRight(short block,int x){
		if (x>Xsize)return false;//out of level
		//start of block see position is lefttop [pos+blocksizen]
		if (((x+blocksize-1)%blocksize==0))return true;
    	return block%Direction.RIGHT.getvalue() != 0;
    }
    private void getpoints(int block){
    	short blockvalue= screendata[block];
    	if ((blockvalue%5==0)){
    		screendata[block] =(short) (blockvalue/5);
    		player.addscore(5);
    		//level.repaint();
    	}
    }
    public boolean CanMoveto(MyPos pos,Direction dir) {
    	int x =pos.x;
    	int y =pos.y;
    	short block = screendata[getblockposition(x,y)];
    	if(Statics.FOLLOW){System.out.print("level canmove?"+dir+pos+"blockval:"+block);} 
    	if (isblockend(pos.y)&&isblockend(pos.y)){
    		getpoints(getblockposition(x,y));
    	}
    		if(Direction.UP== dir){if(Statics.FOLLOW){System.out.print("UP");}
	    		return canMoveUp(block,y)||!isblockend(pos.y);
	    	}
	        if(dir == Direction.DOWN){if(Statics.FOLLOW){System.out.print("DOWN");}
		    	return canMoveDown(block,y);
	        }
	        if(dir == Direction.LEFT){if(Statics.FOLLOW){System.out.print("LEFT");}
	    		return canMoveLeft(block,x);
	    	}
	        if(dir == Direction.RIGHT){if(Statics.FOLLOW){System.out.print("RIGHT");}
	    		return canMoveRight(block,x);
	        }
	        if(dir == Direction.FIXED){
	        	if(Statics.FOLLOW){System.out.println("fixed");}
	        }
		return false;
		//int i = pos.x + (pos.y * NrOfBlocks);
        //(screendata[i] & d.getvalue()) != 0;
    }
    /**
     * @param lenght
     * @return
     * <%@ page contentType="text/html; charset=" %>
	 * player possition is 0,0 of the img and start of block makes going down inposible
	 * <pre>
	 * </pre>
     *
     */
    protected boolean isblockpreend(int lenght){
    	return ((lenght-1)%blocksize==0);
    }
    protected int getblockposition(int x,int y){
    	return (x/blocksize)+(y/blocksize*NrOfBlocks);
    }
	public void LevelInit() {
		//System.arraycopy(leveldata, 0, screendata,0,leveldata.length);
	}
	public void setopponent(Opponent[] opponents) {
		this.opponents = opponents;
	}
	@Override
	public String toString() {
		return "Level["+"]";
	}
	public Opponent MoveOpponent(int i) {
		opponents[i].animate();
		int x=0;
		MyPos pos=player.getpos();
		while(x>10||!CanMoveto(opponents[i].getpos(),opponents[i].getdirection())){
			opponents[i].direction=randomdir();
			//log(Level.INFO,"Set direction@Mylevel:/blockvalue:"+getblockposition(opponents[i].getpos().x, opponents[i].getpos().y)+opponents[i].toString());
			if(opponents[i].getpos().compareTo(pos)==0){
				System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
			}
			x++;
		}
		opponents[i].move();
		return opponents[i];
	}
	public Direction randomdir(){
		switch (1 + (int)(Math.random()*4)) {
		case 4:
			 return Direction.LEFT;
		case 3:
			 return Direction.RIGHT;
		case 2:
			 return Direction.UP;
		case 1:
			 return Direction.DOWN;
		}
		return Direction.RIGHT;
	}
}
